import { nextTick, ref, watch, computed } from 'vue';

export default function useFixed(props) {
  const TITLE_HEIGHT = 30;

  const groupRef = ref(null);
  const listHeight = ref([]); // 每个list的高度区间
  const scrollY = ref(0); // 滚动条纵向滚动的值
  const currentIndex = ref(0); // 当前渲染组的索引
  const distance = ref(0); // 当前组的下一个组距离容器顶部的距离

  const fixedTitle = computed(() => {
    // 如果滚动位置小于0(滚动条位于最顶部或者更上方),不展示fixedTitle
    if (scrollY.value < 0) {
      return '';
    }
    // 通过currentIndex拿到当前group
    const currentGroup = props.data[currentIndex.value];
    return currentGroup ? currentGroup.title : '';
  });

  // 定义css属性
  const fixedStyle = computed(() => {
    const distanceVal = distance.value;
    // 计算偏移量
    // distanceVal > 0 还没进入下一组,无限小的接近下一组,进入下一组之前完成偏移,进入之后y轴的值变为0
    // distanceVal < TITLE_HEIGHT 小于每一个顶部title栏的高度,达到title栏的值就开始进行偏移
    // distanceVal - TITLE_HEIGHT 为负值,translate3d向y轴方向向上移动
    const diff = (distanceVal > 0 && distanceVal < TITLE_HEIGHT) ? distanceVal - TITLE_HEIGHT : 0;
    return {
      transform: `translate3d(0, ${diff}px, 0)`
    };
  });

  // 监测数据变化(监听传入的data数据变化,变更时重新计算高度区间)
  watch(() => {
    return props.data;
  }, async () => {
    // 数据变化了DOM可能还没更新,需要使用nextTick等待DOM更新完毕,再去计算高度
    await nextTick();
    calculate();
  });

  // 监听scrollY的变化(监听滚动)
  watch(scrollY, (newY) => {
    // 对比scrollY的值落在哪个区间内,决定展示哪个区间的内容
    const listHeightValue = listHeight.value;
    // 一开始push了一个0.长度要大一个,所以需要-1
    for (let i = 0; i < listHeightValue.length - 1; i++) {
      // 取得每个list顶部到底部的值
      const heightTop = listHeightValue[i];
      const heightBottom = listHeightValue[i + 1];
      // 判断当前y值落在哪个区间
      if (newY >= heightTop && newY <= heightBottom) {
        currentIndex.value = i;
        // 当前组的底部减去当前滚动条高度
        distance.value = heightBottom - newY;
      }
    }
  });

  // 计算每个list的高度区间
  function calculate() {
    // 拿到每个list的DOM
    const list = groupRef.value.children;
    const listHeightValue = listHeight.value;
    // 记录区间高度
    let height = 0;

    // 清空数组
    listHeightValue.length = 0;
    listHeightValue.push(height);

    // 遍历每个list
    for (let i = 0; i < list.length; i++) {
      // 拿到list高度累加
      // clientHeight为每个list高度
      height += list[i].clientHeight;
      // 将每个list的高度记录在数组里,可以得到每个list的高度区间,从而展示不同的数据
      listHeightValue.push(height);
    }
  }

  // scroll事件,拿到滚动条信息
  function onScroll(pos) {
    scrollY.value = -pos.y;
  }

  return {
    groupRef,
    onScroll,
    fixedTitle,
    fixedStyle,
    currentIndex
  };
}
